#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/kthread.h>
#include <linux/delay.h>
// tasklet处理函数里禁止调度
#include <linux/workqueue.h>
#include "sh3001_reg.h"

#define SH3001_INIT_REG_NUM 10

enum power_mode {
    SH3001_NORMAL = 0,
    SH3001_SLEEP,
    SH3001_POWER_DOWN,
    SH3001_ACC_NORMAL,
    SH3001_POWER_MODE_MAX,
};

struct private_data_irq {
    int irq;
    int flags;
    int gpio;
    char *name;
    // struct tasklet_struct tasklet; // tasklet处理函数里禁止调度
    struct work_struct wq;
};

struct private_data {
    char *name;
    struct i2c_client *sh3001;
    struct input_dev *sh3001_acc_input;
    struct input_dev *sh3001_gyr_input;
    struct input_dev *sh3001_temp_input;
    struct private_data_irq irq_data;
    struct task_struct *thread;
    bool is_interrupt;
    u32 poll_delayms;
    u8 storeAccODR;
};

struct private_data g_private_data = {
    .name = "sh3001",
    .irq_data = {
        .name = "sh3001-int",
    }
};

// i2c_transfer成功返回传输的字节数，失败返回错误码
static int sh3001_read(struct i2c_client *c, u8 reg, u8 *buf, u16 len)
{
    struct i2c_msg msg[2];
    msg[0].addr = c->addr;
    msg[0].buf = &reg;
    msg[0].len = 1;
    msg[0].flags = 0;

    msg[1].addr = c->addr;
    msg[1].buf = buf;
    msg[1].len = len;
    msg[1].flags = I2C_M_RD;

    return i2c_transfer(c->adapter, msg, 2);
}

/*static int sh3001_write(struct i2c_client *c, u8 reg, u8 *buf, u16 len)
{
    struct i2c_msg msg;
    u8 temp[256];
    temp[0] = reg;
    memcpy(&temp[1], buf, len);
    msg.addr = c->addr;
    msg.buf = temp;
    msg.len = len + 1;
    msg.flags = 0;

    return i2c_transfer(c->adapter, &msg, 1);
}*/

static int sh3001_read_reg(struct i2c_client *client, u8 reg, u8 *buf)
{
    struct i2c_msg msgs[2];

	msgs[0].flags = !I2C_M_RD;	//写
	msgs[0].addr  = client->addr;//器件地址
	msgs[0].len   = 1;
	msgs[0].buf   = &reg;

	msgs[1].flags = I2C_M_RD;	//读
	msgs[1].addr  = client->addr;//器件地址
	msgs[1].len   = 1;
	msgs[1].buf   = buf;

	return i2c_transfer(client->adapter, msgs, 2);
}

static int sh3001_write_reg(struct i2c_client *client, u8 reg, u8 data)
{
    struct i2c_msg msg;
	u8 buf[2];

	buf[0] = reg;	//寄存器地址
	buf[1] = data;	//要写入寄存器中的数据

	msg.flags = !I2C_M_RD;	//写
	msg.addr  = client->addr;//器件地址
	msg.len   = 2;
	msg.buf   = buf;

	return i2c_transfer(client->adapter, &msg, 1);
}

static int sh3001_module_reset_mcc(struct i2c_client *client)
{
	u8 regAddr[9] = {0xC0, 0xD3, 0xC2, 0xD3, 0xD5, 0xD4, 0xBB, 0xB9, 0xBA};
	u8 regDataA[9] = {0x38, 0xC6, 0x10, 0xC1, 0x02, 0x0C, 0x18, 0x18, 0x18};
	u8 regDataB[9] = {0x3D, 0xC2, 0x20, 0xC2, 0x00, 0x04, 0x00, 0x00, 0x00};

	//Drive Start
	sh3001_write_reg(client, regAddr[0], regDataA[0]);
	sh3001_write_reg(client, regAddr[1], regDataA[1]);
	sh3001_write_reg(client, regAddr[2], regDataA[2]);
	msleep(300);
	sh3001_write_reg(client, regAddr[0], regDataB[0]);
	sh3001_write_reg(client, regAddr[1], regDataB[1]);
	sh3001_write_reg(client, regAddr[2], regDataB[2]);
	msleep(100);

	//ADC Reset
	sh3001_write_reg(client, regAddr[3], regDataA[3]);
	sh3001_write_reg(client, regAddr[4], regDataA[4]);
	msleep(1);
	sh3001_write_reg(client, regAddr[3], regDataB[3]);
	msleep(1);
	sh3001_write_reg(client, regAddr[4], regDataB[4]);
	msleep(50);

	//CVA Reset
	sh3001_write_reg(client, regAddr[5], regDataA[5]);
	msleep(10);
	sh3001_write_reg(client, regAddr[5], regDataB[5]);

	msleep(1);

	sh3001_write_reg(client, regAddr[6], regDataA[6]);
	msleep(10);
	sh3001_write_reg(client, regAddr[7], regDataA[7]);
	msleep(10);
	sh3001_write_reg(client, regAddr[8], regDataA[8]);
	msleep(10);
	sh3001_write_reg(client, regAddr[6], regDataB[6]);
	msleep(10);
	sh3001_write_reg(client, regAddr[7], regDataB[7]);
	msleep(10);
	sh3001_write_reg(client, regAddr[8], regDataB[8]);
	msleep(10);

	return 0;
}

static int sh3001_module_reset_mcd(struct i2c_client *client)
{
	u8 regAddr[9] = {0xC0, 0xD3, 0xC2, 0xD3, 0xD5, 0xD4, 0xBB, 0xB9, 0xBA};
	u8 regDataA[9] = {0x38, 0xD6, 0x10, 0xD1, 0x02, 0x08, 0x18, 0x18, 0x18};
	u8 regDataB[9] = {0x3D, 0xD2, 0x20, 0xD2, 0x00, 0x00, 0x00, 0x00, 0x00};

	//Drive Start
	sh3001_write_reg(client, regAddr[0], regDataA[0]);
	sh3001_write_reg(client, regAddr[1], regDataA[1]);
	sh3001_write_reg(client, regAddr[2], regDataA[2]);
	msleep(300);
	sh3001_write_reg(client, regAddr[0], regDataB[0]);
	sh3001_write_reg(client, regAddr[1], regDataB[1]);
	sh3001_write_reg(client, regAddr[2], regDataB[2]);
	msleep(100);

	//ADC Reset
	sh3001_write_reg(client, regAddr[3], regDataA[3]);
	sh3001_write_reg(client, regAddr[4], regDataA[4]);
	msleep(1);
	sh3001_write_reg(client, regAddr[3], regDataB[3]);
	msleep(1);
	sh3001_write_reg(client, regAddr[4], regDataB[4]);
	msleep(50);

	//CVA Reset
	sh3001_write_reg(client, regAddr[5], regDataA[5]);
	msleep(10);
	sh3001_write_reg(client, regAddr[5], regDataB[5]);

	msleep(1);

	sh3001_write_reg(client, regAddr[6], regDataA[6]);
	msleep(10);
	sh3001_write_reg(client, regAddr[7], regDataA[7]);
	msleep(10);
	sh3001_write_reg(client, regAddr[8], regDataA[8]);
	msleep(10);
	sh3001_write_reg(client, regAddr[6], regDataB[6]);
	msleep(10);
	sh3001_write_reg(client, regAddr[7], regDataB[7]);
	msleep(10);
	sh3001_write_reg(client, regAddr[8], regDataB[8]);
	msleep(10);

	return 0;
}

static int sh3001_module_reset_mcf(struct i2c_client *client)
{
	u8 regAddr[9] = {0xC0, 0xD3, 0xC2, 0xD3, 0xD5, 0xD4, 0xBB, 0xB9, 0xBA};
	u8 regDataA[9] = {0x38, 0x16, 0x10, 0x11, 0x02, 0x08, 0x18, 0x18, 0x18};
	u8 regDataB[9] = {0x3E, 0x12, 0x20, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00};

	//Drive Start
	sh3001_write_reg(client, regAddr[0], regDataA[0]);
	sh3001_write_reg(client, regAddr[1], regDataA[1]);
	sh3001_write_reg(client, regAddr[2], regDataA[2]);
	msleep(300);
	sh3001_write_reg(client, regAddr[0], regDataB[0]);
	sh3001_write_reg(client, regAddr[1], regDataB[1]);
	sh3001_write_reg(client, regAddr[2], regDataB[2]);
	msleep(100);

	//ADC Reset
	sh3001_write_reg(client, regAddr[3], regDataA[3]);
	sh3001_write_reg(client, regAddr[4], regDataA[4]);
	msleep(1);
	sh3001_write_reg(client, regAddr[3], regDataB[3]);
	msleep(1);
	sh3001_write_reg(client, regAddr[4], regDataB[4]);
	msleep(50);

	//CVA Reset
	sh3001_write_reg(client, regAddr[5], regDataA[5]);
	msleep(10);
	sh3001_write_reg(client, regAddr[5], regDataB[5]);

	msleep(1);

	sh3001_write_reg(client, regAddr[6], regDataA[6]);
	msleep(10);
	sh3001_write_reg(client, regAddr[7], regDataA[7]);
	msleep(10);
	sh3001_write_reg(client, regAddr[8], regDataA[8]);
	msleep(10);
	sh3001_write_reg(client, regAddr[6], regDataB[6]);
	msleep(10);
	sh3001_write_reg(client, regAddr[7], regDataB[7]);
	msleep(10);
	sh3001_write_reg(client, regAddr[8], regDataB[8]);
	msleep(10);

	return 0;
}

static int sh3001_module_reset(struct i2c_client *client)
{
	u8 regData = 0;
    int ret;

	msleep(20);
    ret = sh3001_read_reg(client, SH3001_CHIP_VERSION, &regData);
	if (ret < 0) {
        dev_err(&client->dev, "read SH3001_CHIP_VERSION failed.ret=%d\n", ret);
        return ret;
    }

	if(regData == SH3001_CHIP_VERSION_MCC)
		sh3001_module_reset_mcc(client);
	else if(regData == SH3001_CHIP_VERSION_MCD)
		sh3001_module_reset_mcd(client);
	else if(regData == SH3001_CHIP_VERSION_MCF)
		sh3001_module_reset_mcf(client);
	else
		sh3001_module_reset_mcd(client);

	return 0;
}

static int sh3001_acc_config(struct i2c_client *client,
    u8 accODR,
    u8 accRange,
    u8 accCutOffFreq,
    u8 accFilterEnble)
{
    u8 regData = 0;

    // enable acc digital filter
    sh3001_read_reg(client, SH3001_ACC_CONF0, &regData);
    regData |= 0x01;
    sh3001_write_reg(client, SH3001_ACC_CONF0, regData);

    // set acc ODR
    g_private_data.storeAccODR = accODR;
    sh3001_write_reg(client, SH3001_ACC_CONF1, accODR);

    // set acc Range
    sh3001_write_reg(client, SH3001_ACC_CONF2, accRange);

    // bypass acc low pass filter or not
    sh3001_read_reg(client, SH3001_ACC_CONF3, &regData);
    regData &= 0x17;
    regData |= (accCutOffFreq | accFilterEnble);

return sh3001_write_reg(client, SH3001_ACC_CONF3, regData);
}

static int sh3001_gyro_config(struct i2c_client *client,
    u8 gyroODR,
    u8 gyroRangeX,
    u8 gyroRangeY,
    u8 gyroRangeZ,
    u8 gyroCutOffFreq,
    u8 gyroFilterEnble)
{
    u8 regData = 0;

    // enable gyro digital filter
    sh3001_read_reg(client, SH3001_GYRO_CONF0, &regData);
    regData |= 0x01;
    sh3001_write_reg(client, SH3001_GYRO_CONF0, regData);

    // set gyro ODR
    sh3001_write_reg(client, SH3001_GYRO_CONF1, gyroODR);

    // set gyro X\Y\Z range
    sh3001_write_reg(client, SH3001_GYRO_CONF3, gyroRangeX);
    sh3001_write_reg(client, SH3001_GYRO_CONF4, gyroRangeY);
    sh3001_write_reg(client, SH3001_GYRO_CONF5, gyroRangeZ);

    // bypass gyro low pass filter or not
    sh3001_read_reg(client, SH3001_GYRO_CONF2, &regData);
    regData &= 0xE3;
    regData |= (gyroCutOffFreq | gyroFilterEnble);

    return sh3001_write_reg(client, SH3001_GYRO_CONF2, regData);
}

static int sh3001_temp_config(struct i2c_client *client,
    u8 tempODR,
    u8 tempEnable)
{
    u8 regData = 0;

    // enable temperature, set ODR
    sh3001_read_reg(client, SH3001_TEMP_CONF0, &regData);
    regData &= 0x4F;
    regData |= (tempODR | tempEnable);
    return sh3001_write_reg(client, SH3001_TEMP_CONF0, regData);
}

static int sh3001_interrupt_config(struct i2c_client *client, u8 intEnable0, u8 intEnable1, u8 intConfig)
{
    //u8 regData[2] = {intEnable0, intEnable1};
    // 中断配置
    sh3001_write_reg(client, SH3001_INT_CONF, intConfig);
    // 将中断映射到哪个引脚上　1：int1, 2: int
    sh3001_write_reg(client, SH3001_INT_PIN_MAP1, 0x0);
    // 设置自由落体中断的阈值　0: 0.5g
    sh3001_write_reg(client, SH3001_FREEFALL_INT_THRES, 0x0);
    // 自由落体中断生成时间,计数器频率512HZ，周期2ms
    sh3001_write_reg(client, SH3001_FREEFALL_INT_TIME, 0x0a);
    
    // 中断使能
    //return sh3001_write(client, SH3001_INT_ENABLE0, regData, 2);
    sh3001_write_reg(client, SH3001_INT_ENABLE0, intEnable0);
    sh3001_write_reg(client, SH3001_INT_ENABLE1, intEnable1);
    return 0;
}

static void sh3001_clear_int(struct i2c_client *client)
{
    u8 status;
    sh3001_read_reg(client, SH3001_INT_STA1, &status);
    sh3001_read_reg(client, SH3001_INT_STA0, &status);
}

static int sh3001_sensor_init(struct i2c_client *client, bool is_interrupt)
{
	u8 regData = 0;
	int i = 0;
    int ret;

	// SH3001 chipID = 0x61;
	while ((regData != 0x61) && (i++ < 3)) {
		ret = sh3001_read_reg(client, SH3001_CHIP_ID, &regData);
        if (ret < 0) {
            dev_err(&client->dev, "read SH3001_CHIP_ID error.ret=%d", ret);
            return SH3001_FALSE;
        }
		if ((i == 3) && (regData != 0x61)) {
			dev_err(&client->dev, "check id error,read data:0x%x,ops->id_data:0x%x\n", regData, 0x61);
			return SH3001_FALSE;
		}
	}

	// reset internal module
	if (sh3001_module_reset(client) < 0) {
		dev_err(&client->dev, "Failed to initialize internal module!\n");
		return SH3001_FALSE;
	}

	// 500Hz, 16G, cut off Freq(BW)=500*0.25Hz=125Hz, enable filter;
	sh3001_acc_config(client,
			SH3001_ODR_500HZ,
			SH3001_ACC_RANGE_2G,//使用2G量程
			SH3001_ACC_ODRX025,
			SH3001_ACC_FILTER_EN);

	// 500Hz, X\Y\Z 2000deg/s, cut off Freq(BW)=181Hz, enable filter;
	sh3001_gyro_config(client,
			SH3001_ODR_500HZ,
			SH3001_GYRO_RANGE_2000,
			SH3001_GYRO_RANGE_2000,
			SH3001_GYRO_RANGE_2000,
			SH3001_GYRO_ODRX00,
			SH3001_GYRO_FILTER_EN);

	// temperature ODR is 63Hz, enable temperature measurement
	sh3001_temp_config(client, SH3001_TEMP_ODR_63, SH3001_TEMP_EN);

    if (is_interrupt) {
        ret = sh3001_interrupt_config(client, 0x0, 0xb, 0x5);
        if (ret < 0) {
            dev_err(&client->dev, "sh3001_interrupt_config failed.ret=%d\n", ret);
            return SH3001_FALSE;            
        }
        sh3001_clear_int(client);
    }

	sh3001_read_reg(client, SH3001_CHIP_ID1, &regData);
	if (regData == 0x61)
		dev_info(&client->dev, "New Version SH3001.\n");

	return SH3001_TRUE;
}

static void sh3001_acc_read(struct private_data *d)
{
    u8 acc[6];
    u32 acc_x, acc_y, acc_z;
    sh3001_read(d->sh3001, SH3001_ACC_XL, acc, 6);
    acc_x = (acc[1] << 8) | acc[0];
    acc_y = (acc[3] << 8) | acc[2];
    acc_z = (acc[5] << 8) | acc[4];
    dev_info(&d->sh3001->dev, "acc=(%u,%u,%u)\n", 
        acc_x, acc_y, acc_z);
    input_report_abs(d->sh3001_acc_input, ABS_X, acc_x);
    input_report_abs(d->sh3001_acc_input, ABS_Y, acc_y);
    input_report_abs(d->sh3001_acc_input, ABS_Z, acc_z);
    input_sync(d->sh3001_acc_input);
}

static void sh3001_gyr_read(struct private_data *d)
{
    u8 gyr[6]; // 角速度
    u32 gyr_x, gyr_y, gyr_z;
    sh3001_read(d->sh3001, SH3001_GYRO_XL, gyr, 6);
    gyr_x = (gyr[1] << 8) | gyr[0];
    gyr_y = (gyr[3] << 8) | gyr[2];
    gyr_z = (gyr[5] << 8) | gyr[4];
    dev_info(&d->sh3001->dev, "gyr=(%u,%u,%u)\n", 
        gyr_x, gyr_y, gyr_z);
    input_report_abs(d->sh3001_gyr_input, ABS_X, gyr_x);
    input_report_abs(d->sh3001_gyr_input, ABS_Y, gyr_y);
    input_report_abs(d->sh3001_gyr_input, ABS_Z, gyr_z);
    input_sync(d->sh3001_gyr_input);
}

static void sh3001_temp_read(struct private_data *d)
{
    u8 temp[2]; // 温度
    u8 temperature;
    sh3001_read(d->sh3001, SH3001_TEMP_ZL, temp, 2);
    temperature = (temp[1] & 0x0f << 8) | temp[0];
    dev_info(&d->sh3001->dev, "temp=%u\n", temperature);
    input_report_key(d->sh3001_temp_input, KEY_0, temperature);
    input_sync(d->sh3001_temp_input);
}


static int sh3001_poll_thread(void *data)
{
    struct private_data *d = (struct private_data*)data;
    while (!kthread_should_stop()) {
        dev_info(&d->sh3001->dev, "------------------------\n");
        sh3001_acc_read(d);
        sh3001_gyr_read(d);
        sh3001_temp_read(d);
        dev_info(&d->sh3001->dev, "------------------------\n");        
        msleep(d->poll_delayms);
    }
    return 0;
}

static irqreturn_t sh3001_interrupt_callback(int irq, void *dev)
{
    struct private_data *d = (struct private_data*)dev;
    printk("[%s][%d]\n", __func__, __LINE__);
    // tasklet_schedule(&d->irq_data.tasklet);
    schedule_work(&d->irq_data.wq);
    return IRQ_HANDLED;
}

/*static void sh3001_tasklet_callback(unsigned long arg)
{
    struct private_data *d = (struct private_data*)arg;
    u8 status;
    dev_info(&d->sh3001->dev, "------------------------\n");
    sh3001_read_reg(d->sh3001, SH3001_INT_STA1, &status);
    if (status | (1 << 3)) {
        sh3001_acc_read(d);
    }
    if (status | (1 << 1)) {
        sh3001_gyr_read(d);
    }
    sh3001_read_reg(d->sh3001, SH3001_INT_STA0, &status);
    if (status | (1 << 7)) {
        dev_info(&d->sh3001->dev, "-----------free falling-----------\n");   
        sh3001_acc_read(d);
        sh3001_gyr_read(d);
        dev_info(&d->sh3001->dev, "-----------free falling-----------\n");   
    }
    sh3001_temp_read(d);
    dev_info(&d->sh3001->dev, "------------------------\n");   

}*/

static void sh3001_work_queue_callback(struct work_struct *work)
{
    struct private_data *d = container_of(container_of(work, struct private_data_irq, wq), 
        struct private_data, irq_data);
    u8 status;
    dev_info(&d->sh3001->dev, "------------------------\n");
    sh3001_read_reg(d->sh3001, SH3001_INT_STA1, &status);
    if (status | (1 << 3)) {
        sh3001_acc_read(d);
    }
    if (status | (1 << 1)) {
        sh3001_gyr_read(d);
    }
    sh3001_read_reg(d->sh3001, SH3001_INT_STA0, &status);
    if (status | (1 << 7)) {
        dev_info(&d->sh3001->dev, "-----------free falling-----------\n");   
        sh3001_acc_read(d);
        sh3001_gyr_read(d);
        dev_info(&d->sh3001->dev, "-----------free falling-----------\n");   
    }
    sh3001_temp_read(d);
    dev_info(&d->sh3001->dev, "------------------------\n");
}

static int sh3001_parse_dt(struct private_data *data)
{
    struct private_data_irq *d = &data->irq_data;
    struct device_node *n = data->sh3001->dev.of_node;
    u32 value;
    int ret;
    d->gpio = of_get_named_gpio(n, "gpios", 0);
    if (d->gpio < 0) {
        printk(KERN_ERR "[%s][%d]find gpio failed\n", __func__, __LINE__);
        return -EINVAL;
    }

    d->irq = irq_of_parse_and_map(n, 0);
    if (!d->irq) {
        printk(KERN_ERR "[%s][%d]find irq failed\n", __func__, __LINE__);
        return -EINVAL;
    }

    d->flags = irq_get_trigger_type(d->irq);
    if (d->flags == IRQF_TRIGGER_NONE) {
        d->flags = IRQ_TYPE_EDGE_RISING;
    }

    ret = of_property_read_u32(n, "interrupt-enabled", &value);
    if (ret) {
        dev_err(&data->sh3001->dev, "parse interrupt-enabled err.ret=%d\n", ret);
        return ret;
    }
    data->is_interrupt = (bool)value;

    ret = of_property_read_u32(n, "poll-delayms", &value);
    if (ret) {
        dev_err(&data->sh3001->dev, "parse poll-delayms err.ret=%d\n", ret);
        return ret;
    }
    data->poll_delayms = value;

    return 0;
}

static int sh3001_gpio_init(struct private_data *data)
{
    int ret;
    struct private_data_irq *d = &data->irq_data;
    ret = gpio_request(d->gpio, d->name);
    if (ret) {
        printk(KERN_ERR "[%s][%d]request gpio %d failed.ret=%d\n", __func__, __LINE__, d->gpio, ret);
        return -1;
    }

    ret = gpio_direction_input(d->gpio);
    if (ret) {
        printk(KERN_ERR "[%s][%d]set gpio %d input failed.ret=%d\n", __func__, __LINE__, d->gpio, ret);
        return -2;
    }

    if (data->is_interrupt) {
        ret = request_irq(d->irq, sh3001_interrupt_callback, d->flags, d->name, data);
        if (ret) {
            printk(KERN_ERR "[%s][%d]request sh3001 irq failed.ret=%d\n", __func__, __LINE__, ret);
            return -2;
        }
        INIT_WORK(&d->wq, sh3001_work_queue_callback);
        // tasklet_init(&d->tasklet, sh3001_tasklet_callback, (unsigned long)&g_private_data);
    }    

    return 0;
}

static int sh3001_init_input_device(struct i2c_client *client, struct input_dev **input,
    bool is_abs, const char *name)
{
    int ret;
    /* NOTE: Use input_free_device() to free devices that have not been
     * registered; input_unregister_device() should be used for already
     * registered devices.
     */
    *input = input_allocate_device();
    if (!*input) {
        dev_err(&client->dev, "allocate input device failed\n");
        return -1;
    }
    if (is_abs) {
        /* input_set_abs_params参数说明：
            第一个参数：输入设备
            第二个参数：轴类型(ABS_X, ABS_Y等)
            第三个参数：最小值
            第四个参数：最大值
            第五个参数：fuzz值(噪声)
            第六个参数：flat值(平坦区域)
        */
        input_set_abs_params(*input, ABS_X, 0, 65535, 0, 0);
        input_set_abs_params(*input, ABS_Y, 0, 65535, 0, 0);
        input_set_abs_params(*input, ABS_Z, 0, 65535, 0, 0);
    } else {
        set_bit(EV_KEY, (*input)->evbit);
        set_bit(EV_REP, (*input)->evbit);
        set_bit(KEY_0, (*input)->keybit);
    }
   
    ret = input_register_device(*input);
    if (ret) {
        dev_err(&client->dev, "register input device error\n");
        input_free_device(*input);
        return -2;
    }
    return 0;
}

static int sh3001_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    int ret;
    g_private_data.sh3001 = client;

    printk("[%s][%d]id:%s\n", __func__, __LINE__, id->name);

    ret = sh3001_parse_dt(&g_private_data);
    if (ret) {
        printk(KERN_ERR "[%s][%d]sh3001_parse_dt failed\n", __func__, __LINE__);
        goto SH3001_PARSE_DT_ERR;
    }
    
    ret = sh3001_gpio_init(&g_private_data);
    if (ret == -1) {
        goto SH3001_GPIO_REQ_ERR;
    } else if (ret == -2) {
        goto SH3001_GPIO_DIRECTION_ERR;
    }

    ret = sh3001_init_input_device(g_private_data.sh3001, &g_private_data.sh3001_acc_input, true, "acc");
    if (ret) {
        dev_err(&g_private_data.sh3001->dev, "sh3001_acc input device init err\n");
        ret = -EINVAL;
        goto SH3001_ACC_INPUT_REGISTER_FAILED;
    }

    ret = sh3001_init_input_device(g_private_data.sh3001, &g_private_data.sh3001_gyr_input, true, "gyr");
    if (ret) {
        dev_err(&g_private_data.sh3001->dev, "sh3001_gyr input device init err\n");
        ret = -EINVAL;
        goto SH3001_GYR_INPUT_REGISTER_FAILED;
    }

    ret = sh3001_init_input_device(g_private_data.sh3001, &g_private_data.sh3001_temp_input, false, "temp");
    if (ret) {
        dev_err(&g_private_data.sh3001->dev, "sh3001_temp input device init err\n");
        ret = -EINVAL;
        goto SH3001_TEMP_INPUT_REGISTER_FAILED;
    }

    ret = sh3001_sensor_init(g_private_data.sh3001, g_private_data.is_interrupt);
    if (ret) {
        printk(KERN_ERR "[%s][%d]config sh3001 failed.ret=%d\n", __func__, __LINE__, ret);
        goto SH3001_ACC_CONFIG_ERR;
    }

    if (!g_private_data.is_interrupt) {
        g_private_data.thread = kthread_run(sh3001_poll_thread, &g_private_data, "%s_thread", g_private_data.name);
        if (!g_private_data.thread) {
            printk(KERN_ERR "[%s][%d]create kthread failed\n", __func__, __LINE__);
            ret = -ESRCH;
            goto SH3001_THREAD_CREATE_ERR;
        }
    }

    return 0;

SH3001_THREAD_CREATE_ERR:
    sh3001_module_reset(g_private_data.sh3001);
SH3001_ACC_CONFIG_ERR:
    input_unregister_device(g_private_data.sh3001_temp_input);
SH3001_TEMP_INPUT_REGISTER_FAILED:
    input_unregister_device(g_private_data.sh3001_gyr_input);
SH3001_GYR_INPUT_REGISTER_FAILED:
    input_unregister_device(g_private_data.sh3001_acc_input);
SH3001_ACC_INPUT_REGISTER_FAILED:
    if (g_private_data.is_interrupt) {
        // tasklet_kill(&g_private_data.irq_data.tasklet);
        free_irq(g_private_data.irq_data.irq, &g_private_data);
    }
SH3001_GPIO_DIRECTION_ERR:
    gpio_free(g_private_data.irq_data.gpio);
SH3001_GPIO_REQ_ERR:
SH3001_PARSE_DT_ERR:
    return ret;
}

static int sh3001_remove(struct i2c_client *client)
{
    if (!g_private_data.is_interrupt) {
        kthread_stop(g_private_data.thread);
    }    
    sh3001_module_reset(g_private_data.sh3001);
    input_unregister_device(g_private_data.sh3001_temp_input);    
    input_unregister_device(g_private_data.sh3001_gyr_input);
    input_unregister_device(g_private_data.sh3001_acc_input);
    if (g_private_data.is_interrupt) {
        // tasklet_kill(&g_private_data.irq_data.tasklet);
        free_irq(g_private_data.irq_data.irq, &g_private_data);
    }
    gpio_free(g_private_data.irq_data.gpio);
    return 0;
}

static struct of_device_id g_sh3001_acc_match_table[] = {
    {.compatible = "guoerba,sh3001_acc"},
};

static struct i2c_driver g_sh3001_acc_driver = {
    .probe = sh3001_probe,
    .remove = sh3001_remove,
    .driver = {
        .name = "sh3001_acc",
        .of_match_table = g_sh3001_acc_match_table,
    }
};

static int __init rk3588_i2c_init(void)
{
    int ret = i2c_add_driver(&g_sh3001_acc_driver);
    if (ret) {
        printk(KERN_ERR "[%s][%d]register i2c driver failed.ret=%d\n", __func__, __LINE__, ret);
        return ret;
    }
    return 0;
}

static void __exit rk3588_i2c_exit(void)
{
    i2c_del_driver(&g_sh3001_acc_driver);
}

module_init(rk3588_i2c_init);
module_exit(rk3588_i2c_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yujie Guo");
MODULE_DESCRIPTION("rk3588-i2c driver for Learning");
